/**
 * @file wifi_station.h
 * @brief Wi-Fi 站点模式管理器头文件
 * 
 * 该文件定义了Wi-Fi站点模式管理器类，用于管理ESP32作为Wi-Fi客户端
 * 连接到路由器或热点。支持自动扫描、智能连接、信号强度监测等功能。
 * 
 * @author SiaZhang
 * @version 2.4.2
 */

#ifndef _WIFI_STATION_H_
#define _WIFI_STATION_H_

#include <string>
#include <vector>
#include <functional>

#include <esp_event.h>
#include <esp_timer.h>
#include <esp_wifi_types_generic.h>

/**
 * @brief Wi-Fi接入点记录结构体
 * 
 * 存储扫描到的Wi-Fi接入点的详细信息，用于连接队列管理
 */
struct WifiApRecord {
    std::string ssid;                   ///< Wi-Fi网络名称
    std::string password;               ///< Wi-Fi网络密码
    int channel;                        ///< Wi-Fi信道号
    wifi_auth_mode_t authmode;          ///< 认证模式（开放/WPA/WPA2等）
    uint8_t bssid[6];                   ///< 接入点MAC地址
};

/**
 * @brief Wi-Fi站点模式管理器类
 * 
 * 使用单例模式实现的Wi-Fi客户端管理器，主要功能：
 * - 自动扫描周围的Wi-Fi网络
 * - 按信号强度排序并智能连接
 * - 支持多网络自动切换
 * - 提供连接状态监控和回调
 * - 支持功率管理和省电模式
 * - 自动重连机制
 */
class WifiStation {
public:
    /**
     * @brief 获取单例实例
     * @return WifiStation& 单例对象引用
     */
    static WifiStation& GetInstance();

    /**
     * @brief 手动添加Wi-Fi网络认证信息
     * 
     * @param ssid Wi-Fi网络名称
     * @param password Wi-Fi网络密码
     * 
     * 注意：此方法会将网络信息保存到SSID管理器中
     */
    void AddAuth(const std::string &&ssid, const std::string &&password);

    /**
     * @brief 启动Wi-Fi站点模式
     * 
     * 初始化Wi-Fi协议栈，注册事件处理器，开始扫描和连接流程
     */
    void Start();

    /**
     * @brief 停止Wi-Fi站点模式
     * 
     * 清理资源，注销事件处理器，停止Wi-Fi服务
     */
    void Stop();

    /**
     * @brief 检查Wi-Fi连接状态
     * @return bool 如果已连接返回true，否则返回false
     */
    bool IsConnected();

    /**
     * @brief 等待Wi-Fi连接完成
     * 
     * @param timeout_ms 等待超时时间（毫秒），默认10秒
     * @return bool 连接成功返回true，超时返回false
     */
    bool WaitForConnected(int timeout_ms = 10000);

    /**
     * @brief 获取当前Wi-Fi信号强度
     * @return int8_t 信号强度值（dBm），负值，绝对值越小信号越强
     */
    int8_t GetRssi();

    /**
     * @brief 获取当前连接的Wi-Fi网络名称
     * @return std::string 当前连接的SSID
     */
    std::string GetSsid() const { return ssid_; }

    /**
     * @brief 获取当前分配的IP地址
     * @return std::string IP地址字符串
     */
    std::string GetIpAddress() const { return ip_address_; }

    /**
     * @brief 获取当前Wi-Fi信道号
     * @return uint8_t 信道号（1-14）
     */
    uint8_t GetChannel();

    /**
     * @brief 设置Wi-Fi省电模式
     * 
     * @param enabled true启用省电模式，false禁用
     * 
     * 省电模式可以降低功耗，但可能影响网络响应速度
     */
    void SetPowerSaveMode(bool enabled);

    /**
     * @brief 设置Wi-Fi连接开始回调
     * 
     * @param on_connect 连接开始时的回调函数，参数为SSID
     * 
     * 该回调在开始尝试连接某个网络时触发
     */
    void OnConnect(std::function<void(const std::string& ssid)> on_connect);

    /**
     * @brief 设置Wi-Fi连接成功回调
     * 
     * @param on_connected 连接成功时的回调函数，参数为SSID
     * 
     * 该回调在成功连接并获取IP地址时触发
     */
    void OnConnected(std::function<void(const std::string& ssid)> on_connected);

    /**
     * @brief 设置Wi-Fi扫描开始回调
     * 
     * @param on_scan_begin 扫描开始时的回调函数
     * 
     * 该回调在开始扫描Wi-Fi网络时触发
     */
    void OnScanBegin(std::function<void()> on_scan_begin);

    /**
     * @brief 设置Wi-Fi扫描完成回调
     * 
     * @param on_scan_down 扫描完成时的回调函数，参数为扫描到的AP数量和AP记录数组
     * 
     * 该回调在Wi-Fi网络扫描完成时触发，可以获取扫描结果
     */
    void OnScanDown(std::function<void(uint16_t ap_num, wifi_ap_record_t* ap_records)> on_scan_down);

    /**
     * @brief 设置Wi-Fi断开连接回调
     * 
     * @param on_disconnect 断开连接时的回调函数
     * 
     * 该回调在Wi-Fi连接断开时触发
     */
    void OnDisconnect(std::function<void()> on_disconnect);
private:
    /**
     * @brief 私有构造函数（单例模式）
     * 
     * 初始化事件组和相关配置，从NVS读取高级设置
     */
    WifiStation();

    /**
     * @brief 私有析构函数（单例模式）
     * 
     * 清理事件组资源
     */
    ~WifiStation();

    // 禁用拷贝构造和赋值操作（单例模式）
    WifiStation(const WifiStation&) = delete;
    WifiStation& operator=(const WifiStation&) = delete;

    EventGroupHandle_t event_group_;                                    ///< FreeRTOS事件组句柄
    esp_timer_handle_t timer_handle_ = nullptr;                        ///< 定时器句柄（用于定时扫描）
    esp_event_handler_instance_t instance_any_id_ = nullptr;           ///< Wi-Fi事件处理器实例
    esp_event_handler_instance_t instance_got_ip_ = nullptr;           ///< IP事件处理器实例
    std::string ssid_;                                                  ///< 当前连接的SSID
    std::string password_;                                              ///< 当前连接的密码
    std::string ip_address_;                                            ///< 当前IP地址
    int8_t max_tx_power_;                                               ///< 最大发射功率
    uint8_t remember_bssid_;                                            ///< 是否记住BSSID
    int reconnect_count_ = 0;                                           ///< 重连计数器
    std::function<void(const std::string& ssid)> on_connect_;          ///< 连接开始回调
    std::function<void(const std::string& ssid)> on_connected_;        ///< 连接成功回调
    std::function<void()> on_disconnect_;                              ///< 断开连接回调
    std::function<void()> on_scan_begin_;                              ///< 扫描开始回调
    std::function<void(uint16_t ap_num, wifi_ap_record_t* ap_records)> on_scan_down_;                               ///< 扫描完成回调
    std::vector<WifiApRecord> connect_queue_;                          ///< 连接队列（按信号强度排序）

    /**
     * @brief 处理Wi-Fi扫描结果
     * 
     * 解析扫描结果，按信号强度排序，构建连接队列
     */
    void HandleScanResult();

    /**
     * @brief 开始连接Wi-Fi网络
     * 
     * 从连接队列中取出第一个网络进行连接尝试
     */
    void StartConnect();

    /**
     * @brief Wi-Fi事件处理器（静态方法）
     * 
     * @param arg 用户参数（WifiStation实例指针）
     * @param event_base 事件基础类型
     * @param event_id 事件ID
     * @param event_data 事件数据
     */
    static void WifiEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);

    /**
     * @brief IP事件处理器（静态方法）
     * 
     * @param arg 用户参数（WifiStation实例指针）
     * @param event_base 事件基础类型
     * @param event_id 事件ID
     * @param event_data 事件数据
     */
    static void IpEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
};

#endif // _WIFI_STATION_H_
